#include "mysql_pool.h"

#include "mysql_handle.h"

#include <chrono>
#include <memory>
#include <mutex>

MySQLPool::MySQLPool(const std::string &host,
                     uint16_t           port,
                     const std::string &username,
                     const std::string &password,
                     const std::string &database,
                     uint32_t           poolSize)
{
    for (size_t i = 0; i < poolSize; i++) {
        pool_.push(new MySQLHandle(host, port, username, password, database));
    }
}

MySQLPool::~MySQLPool()
{
    while (!pool_.empty()) {
        auto conn = pool_.front();
        pool_.pop();
        delete conn;
    }
}

std::shared_ptr<MySQLConnection> MySQLPool::acquire()
{
    std::unique_lock<std::mutex> lock(mutex_);
    while (pool_.empty()) {
        cond_.wait_for(lock, std::chrono::seconds(1));
    }
    MySQLHandle *handle = pool_.front();
    pool_.pop();
    return std::make_shared<MySQLConnection>(this, handle);
}

void MySQLPool::release(MySQLHandle *handle)
{
    {
        std::lock_guard<std::mutex> lock(mutex_);
        pool_.emplace(std::move(handle));
    }
    cond_.notify_one();
}